package zack.project.domain.activity.service.armory;

import zack.project.domain.activity.adapter.repository.IActivityRepository;
import zack.project.domain.activity.model.entity.ActivitySkuEntity;
import zack.project.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class ActivityArmory implements IActivityArmory, IActivityDispatch {

    @Resource
    private IActivityRepository activityRepository;

    /**
     * 根据活动id去装配 ActivityEntity,ActivityCountEntity,ActivitySkuEntity.surplus
     *装配活动，抽奖sku商品的抽奖次数，抽奖sku商品的库存
     * @param activityId
     * @return
     */
    @Override
    public boolean assembleActivitySkuByActivityId(Long activityId) {
        //id sku   activity_id  activity_count_id   total_count     surplus payAmount
        //1	9011	100301	    11101	            100000	        99887	200.00	2024-03-16 11:41:09	2024-06-22 08:49:32
        //2	9012	100301	    11102	            100000	        99885	100.00	2024-03-16 11:41:09	2024-06-22 11:46:15
        //3	9013	100301	    11103	            100000	        99884	20.00	2024-03-16 11:41:09	2024-06-22 11:45:55
        //4	9014	100301	    11104	            100000	        99866	5.00	2024-03-16 11:41:09	2024-06-22 11:45:50
        //在数据库表{raffle_activity_sku}中根据活动id去查找对应的sku配置 将抽奖次数视为商品，根据不同抽奖次数activity_count_id可配置不同的sku
        List<ActivitySkuEntity> skuEntities = activityRepository.queryActivitySkuListByActivityId(activityId);

        for (ActivitySkuEntity skuEntity : skuEntities) {
            //缓存当前sku商品的库存数量 cacheKey:"activity_sku_count_key_#{sku}",value = surplus
            cacheActivitySkuStockCount(skuEntity.getSku(), skuEntity.getStockCountSurplus());
            //预热当前sku商品的抽奖次数配置
            // cacheKey:"activity_count_key_#{activityCountId}",value = ActivityCountEntity
            activityRepository.queryRaffleActivityCountByActivityCountId(skuEntity.getActivityCountId());
        }
        //预热ActivityEntity
        activityRepository.queryRaffleActivityByActivityId(activityId);
        return true;

    }

    @Override
    public boolean assembleActivitySku(Long sku) {

        ActivitySkuEntity activitySkuEntity = activityRepository.queryActivitySku(sku);
        // 预热活动sku库存
        cacheActivitySkuStockCount(sku, activitySkuEntity.getStockCountSurplus());
        // 预热活动【查询时预热到缓存】

        activityRepository.queryRaffleActivityByActivityId(activitySkuEntity.getActivityId());

        // 预热活动次数【查询时预热到缓存】
        activityRepository.queryRaffleActivityCountByActivityCountId(activitySkuEntity.getActivityCountId());
        return true;
    }

    private void cacheActivitySkuStockCount(Long sku, Integer stockCount) {
        String cacheKey = Constants.RedisKey.ACTIVITY_SKU_STOCK_COUNT_KEY + sku;
        activityRepository.cacheActivitySkuStockCount(cacheKey, stockCount);

    }

    /**
     * 扣减sku库存，先在缓存中根据"activity_sku_stock_count_key_#{sku}"进行decr扣减操作，
     * 再设置一个"activity_sku_stock_count_key_#{sku}_#{surplus}"的抢占锁，并且当该sku商品对应的库存为0时，
     * 会发送一个ActivitySkuStockZeroMessageEvent消息
     * @param sku
     * @param endDateTime
     * @return
     */
    @Override
    public boolean subtractionActivitySkuStock(Long sku, Date endDateTime) {
        String cacheKey = Constants.RedisKey.ACTIVITY_SKU_STOCK_COUNT_KEY + sku;

        return activityRepository.subtractionActivitySkuStock(sku, cacheKey, endDateTime);
    }
}
